home *** CD-ROM | disk | FTP | other *** search
- #include "main.h"
-
- #define asyncTrapBit 0x400
-
- /**************************************************************
- * *
- * The following are the 'oldFileTraps' that are patched, or not, according to the contents *
- * of the whichTraps arrays. Traps that are already patched *are* patched, but are *
- * treated differently. The replacement routine replaces the trap dispatcher's return addr *
- * on the stack with its own, so that it will regain control without disrupting whatever *
- * stack peeking Apple's patches are doing. This makes it 'safe' to do tail patches. *
- * *
- * Generally speaking, those that could take an appreciable amount of time are patched, *
- * while those that don't usually are not. At the very least, status, control, getvol, and *
- * setvol must not be patched, as some DAs and multifinder repeatedly call these. *
- * Also, mountvol, unmountvol, and initqueue cannot be called asyncronously. *
- * *
- * 0 = open 1 = close 2 = read 3 = write 4 = control *
- * 5 = status 6 = killio 7 = getvolinfo 8 = create 9 = delete *
- * a = openrf b = rename c = getfileinfo d = setfileinfo e = unmountvol *
- * f = mountvol 10 = allocate 11 = geteof 12 = seteof 13 = flushvol *
- * 14 = getvol 15 = setvol 16 = initqueue 17 = eject 18 = getfpos *
- * *
- * 41 = setfillock 42 = rstfillock 43 = setfiltype 44 = setfpos 45 = flushfile *
- * *
- **************************************************************/
-
- #define trapCount 0x46
-
- long oldFileTraps[ trapCount ];
- int whichTraps[ trapCount ] =
- { 1,1,1,1,0, 0,0,1,1,1, 1,1,1,1,0, 0,1,0,1,1,
- 0,0,0,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
- 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
- 0,0,0,0,0, 1,1,1,1,1 };
-
- /**************************************************************
- * *
- * *
- **************************************************************/
-
- doFileBackground() {
- doBackground( lotsElseToDo, noGray, NULL );
- }
-
- /**************************************************************
- * *
- * trap dispatcher calls the OS routines with d1, d2, ?a0?, a1, and a2 saved, and with *
- * d1 holding the original trap word, d2 holding the trap table offset, and a2 holding the *
- * address of the trap. Bit 10 of d1 tells us whether the trap was async or not. *
- * *
- **************************************************************/
-
- int trapWord; /* the original trap word, gotten for us by the trap dispatcher. */
- ParmBlkPtr parms;
- long completion, /* the old completion routine value for sync calls converted */
- dispatcher; /* the dispatcher return address, so I can get away with tail patching */
-
-
- long theMem[0x400], /* trapWord, parms, completion, dispatcher */
- *storage = theMem;
-
- #define trapWord 0
- #define parms 4
- #define completion 8
- #define dispatcher 12
- #define storageCount 16
-
- doFileTrap()
- {
- int fake; /* forces link - otherwise it's not for sure */
- asm {
- unlk a6
- move.l a5,-(sp)
- move.l CurrentA5,a5
- add.l #storageCount,storage
- move.l storage,a1
- move d1,trapWord(a1)
- move.l a0,parms(a1)
-
- and #0xff,d1
- lsl #2,d1 /* this is also done in dispatcher, is in d2, but don't want */
- lea oldFileTraps,a2 /* to depend on it being *4 - older ones are *2. */
- move.l 0(a2,d1.w),a2
- move trapWord(a1),d1
-
- bset #10,d1
- bne @isAsync1
- move.l OFFSET(ioParam,ioCompletion)(a0),completion(a1)
- clr.l OFFSET(ioParam,ioCompletion)(a0)
- isAsync1: move.l 4(sp),dispatcher(a1) /* save dispatcher return address */
- move.l (sp)+,a5 /* restore globals pointer */
- addq.l #4,sp /* clear dispatcher return address */
- jsr (a2) /* call wherever, even a patch! */
- subq.l #4,sp /* make room for disp. addr. */
- move.l a5,-(sp) /* save old globals pointer */
- move.l CurrentA5,a5 /* get our own. */
- move.l storage,a1
- move.l dispatcher(a1),4(sp) /* restore dispatcher return addr */
-
- move.l d1,-(sp)
- move trapWord(a1),d1
- btst #10,d1
- bne @isAsync
- movem.l d2-d7/a0-a4,-(sp)
- bra @waitSkip
- waitDone: jsr doFileBackground
- move.l storage,a1
- waitSkip: move.l parms(a1),a2
- cmp #1,OFFSET(ioParam,ioResult)(a2)
- beq @waitDone
- move OFFSET(ioParam,ioResult)(a2),d0
- move.l completion(a1),OFFSET(ioParam,ioCompletion)(a2)
- movem.l (sp)+,d2-d7/a0-a4
- isAsync: sub.l #storageCount,storage
- move.l (sp)+,d1
- move.l (sp)+,a5
- rts
- }
- }
-
- installFileTraps() {
- int i;
-
- for( i = 0; i < trapCount; ++i )
- if( whichTraps[ i ] ) {
- oldFileTraps[ i ] = NGetTrapAddress( i, OSTrap );
- NSetTrapAddress( doFileTrap, i, OSTrap );
- }
- }
-
- removeFileTraps() {
- int i;
-
- for( i = 0; i < trapCount; ++i )
- if( whichTraps[ i ] )
- NSetTrapAddress( oldFileTraps[ i ], i, OSTrap );
- }
-
- fixup() {
- int fake;
-
- removeFileTraps();
- DebugStr( "\pFile Traps Removed." );
- }
-